from PIL import Image
import pandas as pd
import openpyxl
import os
import tkinter as tk
import time
import threading
from tkinter import messagebox

modelIdNameList = ["NPC模型#客户端#C","怪物模型"]
heightName = "高度"


# def find_column_number(df, target_string):
#     """
#     遍历 Excel 文件的第一行，查找等于某个字符串的列名，并返回其列数。

#     :param df: Excel数据
#     :param target_string: 目标字符串（列名）
#     :return: 列数（从 0 开始），如果未找到则返回 -1
#     """
#     try:
#         # 获取第一行（列名）
#         columns = df.columns.tolist()

#         # 遍历列名，查找目标字符串
#         for index, column_name in enumerate(columns):
#             if column_name == target_string:
#                 return index  # 返回列数（从 0 开始）

#         return -1  # 如果未找到，返回 -1
#     except Exception as e:
#         print(f"发生错误: {e}")
#         return -1

def is_pure_number(s):
    """
    判断字段是否是纯数字。
    :param s: 输入的字段（字符串或数字）
    :return: True（是纯数字）或 False（不是纯数字）
    """
    return str(s).isdigit()

def find_and_process_files(excel_path, search_column, result_column, resource_path):
    """
    读取 Excel 文件中的某一列数据，根据该数据在资源路径中查找文件，
    处理文件后将结果写入 Excel 文件的另一列，并保留原有格式。

    :param excel_path: Excel 文件路径
    :param search_column: 要读取的列名（用于查找文件）
    :param result_column: 要写入结果的列名
    :param resource_path: 资源文件夹路径
    """
    try:
        # 使用 openpyxl 加载 Excel 文件以保留格式
        workbook = openpyxl.load_workbook(excel_path)
        sheet = workbook.active

        # 将 Excel 数据加载到 pandas DataFrame
        data = sheet.values
        columns = next(data)  # 第一行是列名
        df = pd.DataFrame(data, columns=columns)

        # 检查列是否存在
        if search_column not in df.columns:
            messagebox.showerror("错误", f"未找到指定列数，请确认属性名中存在 '{search_column}'")
            raise ValueError(f"列 '{search_column}' 不存在于 Excel 文件中")

        # 如果结果列不存在，创建该列
        if result_column not in df.columns:
            df[result_column] = None

        # 遍历 Excel 文件的每一行
        for index, row in df.iterrows():
            search_value = str(row[search_column])  # 获取查找值
            if not is_pure_number(search_value):
                continue

            # 构造文件路径
            found_file = os.path.join(resource_path, f"{search_value}_STAND_4", "0.png")

            # 处理找到的文件并写入结果
            if os.path.exists(found_file):
                result = get_opaque_height(found_file)  # 调用自定义函数处理文件
                df.at[index, result_column] = result  # 更新 DataFrame 中的结果
                # 将结果写回 Excel 文件并保留格式
                sheet.cell(row=index + 2, column=df.columns.get_loc(result_column) + 1, value=result)
            else:
                df.at[index, result_column] = 0  # 如果未找到文件，写入 0
                sheet.cell(row=index + 2, column=df.columns.get_loc(result_column) + 1, value=0)

        # 保存修改后的 Excel 文件
        workbook.save(excel_path)
        messagebox.showinfo("成功", f"处理完成，结果已写入 {excel_path}")
    except Exception as e:
        messagebox.showerror("错误", f"处理过程中发生错误: {e}")
        raise


def get_opaque_height(image_path):
    """
    获取 PNG 图像中不透明元素的高度（即使不透明元素不连续）。

    :param image_path: PNG 图像路径
    :return: 不透明元素的高度（像素），如果没有不透明元素则返回 0
    """
    try:
        image = Image.open(image_path).convert("RGBA")
    except Exception as e:
        return 0
    width, height = image.size

    # 获取图像数据
    data = image.getdata()

    # 初始化最小和最大 Y 坐标
    min_y = height/2
    max_y = 0

    # 遍历所有像素
    for y in reversed(range(height)):
        for x in range(width):
            pixel = data[y * width + x]
            if pixel[3] != 0:  # 检查 alpha 通道是否不透明
                max_y = height - y
                break
            
    # 计算高度
    if  max_y != 0:
        return  round(max_y - min_y) 
    else:
        return 0  # 如果没有不透明元素，返回 0

def startWork(excel_path,resource_path):
    button.config(state=tk.DISABLED, text="执行中")
        # 使用线程执行耗时任务，避免界面卡住
    def run_task():
        try:
            # df = pd.read_excel(excel_path)
            # modelIdColumn = find_column_number(df, modelIdName)
            # heightColumn = find_column_number(df,heightName)
            # print(modelIdColumn,heightColumn)
            # if modelIdColumn == -1 or heightColumn == -1:
            #     messagebox.showerror("错误", f"未找到指定列数，请确认属性名中存在\"{modelIdName}\"和\"{heightName}\"")
            #     button.config(state=tk.NORMAL, text="开始")
            #     return
            find_and_process_files(excel_path,modelIdNameList[unitTypeInt.get()],heightName,resource_path)
            time.sleep(5)
        except Exception as e:
            messagebox.showerror("错误", f"处理过程中发生错误: {e}")
            button.config(state=tk.NORMAL, text="开始")
            raise ValueError(f"无法读取 Excel 文件: {e}")
        # 任务完成后恢复按钮状态
        button.config(state=tk.NORMAL, text="开始")
    threading.Thread(target=run_task).start()
    

root = tk.Tk()
root.title("批量获取png高度工具")
# 设置窗口大小
root.geometry("450x320")
# 创建一个标签，用于显示用户的选择
label = tk.Label(root, text="选择单位类型: ")
label.pack()
unitTypeInt = tk.IntVar()
radio1 = tk.Radiobutton(root, text="npc", variable=unitTypeInt, value=0)
radio2 = tk.Radiobutton(root, text="monster", variable=unitTypeInt, value=1)
radio1.select()
radio1.pack()
radio2.pack()

frame2 = tk.Frame(root)
frame2.pack()
label0 = tk.Label(frame2, text="请填写excel地址,例:xxxxx/Data/Branch/table/workbook/monsters.xlsx\n 注意需要关闭该文件")
label0.grid(row=0, column=0,columnspan=2, padx=10, pady=10)
# 第一行：Label 和 Input
label1 = tk.Label(frame2, text="excel文件地址：")
label1.grid(row=1, column=0, padx=10, pady=10)
entry1 = tk.Entry(frame2)
entry1.grid(row=1, column=1, padx=10, pady=10)
# 第二行：Label 和 Input
label2 = tk.Label(frame2, text="填写资源目录，例:xxxxxxx/Art/GameRes/Monster")
label2.grid(row=2, column=0,columnspan=2, padx=10, pady=10)
label3 = tk.Label(frame2, text="资源文件夹地址:")
label3.grid(row=3, column=0, padx=10, pady=10)
entry2 = tk.Entry(frame2)
entry2.grid(row=3, column=1, padx=10, pady=10)
# 按钮
button = tk.Button(frame2, text="开始", command=lambda: startWork(entry1.get(), entry2.get()))
button.grid(row=4, column=0, columnspan=2, pady=10)
# 运行主循环
root.mainloop()


